package tasks;

import java.util.Collections;
import java.util.Comparator;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Queue;

public class TaskPool extends LinkedList<ITask> {
	private static TaskListUpdatedObservable _taskListUpdated = null;
	
	private static final long serialVersionUID = 1L;
	
	private static TaskPool _instance = null;
	
	public/*private*/ LinkedList<ITask> _performedTasks = null;

	class TaskListUpdatedObservable extends Observable {
		public void setContentChanged() {
			this.setChanged();
		}
	}

    private TaskPool() {
    	_taskListUpdated = new TaskListUpdatedObservable() {};
    	_performedTasks = new LinkedList<ITask>();
    }
    
    public static synchronized TaskPool getInstance() {
        if (_instance == null)
            _instance = new TaskPool();
        return _instance;
    }
    
    public Observable getTaskListUpdatedObservable() {
    	return _taskListUpdated;
    }
    
    class TaskListComparator implements Comparator<ITask> {
		@Override
		public int compare(ITask o1, ITask o2) {
			if (o1==null && o2!=null)
				return 1;
			if (o1!=null && o2==null)
				return -1;
			if (o1==null && o2==null)
				return 0;
			if (o1.isActive()==true && o2.isActive()==false)
				return -1;
			if (o1.isActive()==false && o2.isActive()==true)
				return 1;
			if (o1.isActive()==o2.isActive()==false) {
				if (o1.getLastError()==null && o2.getLastError()!=null)
					return -1;
				if (o1.getLastError()!=null && o2.getLastError()==null)
					return 1;
			}
			return o1.getDescription().compareTo(o2.getDescription());
		}
    }
    
    @Override
    public boolean add(ITask e) {
    	boolean added = super.add(e);
    	Collections.sort(this, new TaskListComparator());
    	for (ITask t : this)
    		if (t!=null)
    			System.out.println(t.getDescription()+" "+t.getTargetModuleName()+" "+Boolean.toString(t.isActive())+" ");
    	_taskListUpdated.setContentChanged();
    	/** No need to send ITask, just notification */
    	_taskListUpdated.notifyObservers();
    	return added;
    }
    
    public void moveToQueue(ITask task) {
    	if (contains(task)) {
    		_performedTasks.push(task);
    		remove(task);
    	}
    }
    
    public ITask getLastPerformedTask() {
    	if (_performedTasks.size()>0)
    		return _performedTasks.peek();// .element();
    	return null;
    }
    
    public ITask popLastPerformedTask() {
    	if (_performedTasks.size()>0)
    		return _performedTasks.pop();
    	return null;
    }
    
    public LinkedList<ITask> getPerformedTasks() {
    	return _performedTasks;
    }
}
